home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Oh!X 2000 Spring
/
Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z
/
Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin
/
F2JW
/
trans
/
print.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-08-22
|
47KB
|
1,555 lines
#include "stdafx.h"
#include <string.h>
#include <ctype.h>
// #include <iostream.h>
#include "f2j.h"
#include "myprot.h"
extern TOKEN *currentTree;
extern JP_UNIT_INFO jpUnitInforTable[];
extern const char *jpVerbTailTable_Keiyoshi[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_KeiyoDoshi[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Rentaishi[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Adverb[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Devoir[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Falloir[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Pouvoir[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Godan[15][JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Upper1[15];
extern const char *jpVerbTailTable_Lower1[15];
extern const char *jpVerbTailTable_Noroot[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Other[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Other2[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Kahen[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Sahen[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Sahen2[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Aru[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Masu[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Rasii[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Ta[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Da[JP_CHANGE_LAST];
extern const char *jpVerbTailTable_Desu[JP_CHANGE_LAST];
// 動詞にかかる言葉の優先順位
FR_PATTERN verbSortTable[] = {
FR_PATTERN( CMP_TOKEN( FR_PART_ADJECTIVE_EXCLAMINATION), 9 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ADVERB_EXCLAMINATION), 9 ),
FR_PATTERN( CMP_TOKEN( FR_PART_SENTENCE_ALL), 8 ),
FR_PATTERN( CMP_TOKEN( FR_PART_PREPOSIT_QUAND), 7 ),
FR_PATTERN( CMP_TOKEN( FR_PART_INDEPENDENCE_ALL), 10 ),
FR_PATTERN( CMP_TOKEN( FR_PART_PREPOSIT_EN_ENT), 5 ),
FR_PATTERN( CMP_TOKEN( FR_PART_RELATIVE_ALL), 4 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ADJECTIVE_ALL), 3 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ALL), 2 ),
FR_PATTERN( CMP_TOKEN( FR_PART_NONE )),
};
//
// 助詞をメタキャラから表示
//
BOOL
PrintOutJpPreposition(char *s, JP_EMPHASIS jpEmphasis, PRT_CONTROL prtControl)
{
char t[100];
t[0] = '\0';
if(StringCmp(s, "A")) {
if(jpEmphasis & JP_EMPHASIS_HOU) strcat(t, "の方");
if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "のことしか");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "のことだけ");
else if(jpEmphasis & JP_EMPHASIS_DEMO) strcat(t, "のことでも");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "のことも");
else strcat(t, "のことが");
} else if(StringCmp(s, "B")) {
if(jpEmphasis & JP_EMPHASIS_HOU) strcat(t, "の方");
if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "のことしか");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "のことだけ");
else if(jpEmphasis & JP_EMPHASIS_DEMO) strcat(t, "のことでも");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "のことも");
else strcat(t, "のことを");
} else if(StringCmp(s, "C")) {
if(jpEmphasis & JP_EMPHASIS_GA) strcat(t, "に");
else if(jpEmphasis & JP_EMPHASIS_DEMO) strcat(t, "にも");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "にも");
else if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "しか");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
else strcat(t, "には");
} else if(StringCmp(s, "D")) {
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "で");
} else if(StringCmp(s, "E")) {
if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "へしか");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "へも");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "へだけ");
else strcat(t, "へ");
} else if(StringCmp(s, "F")) {
if(jpEmphasis & JP_EMPHASIS_HOU) strcat(t, "事の方");
else if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "事しか");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "事だけ");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "事も");
else strcat(t, "事が");
} else if(StringCmp(s, "G")) {
if(jpEmphasis & JP_EMPHASIS_HOU) strcat(t, "の方");
if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "しか");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけが");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
else strcat(t, "が");
} else if(StringCmp(s, "H")) {
// La voiture, c'est belle.
if(jpEmphasis & JP_EMPHASIS_CE) strcat(t, "こそ");
if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
else if(jpEmphasis & JP_EMPHASIS_GA) strcat(t, "が");
// else if(jpEmphasis & JP_EMPHASIS_NI) strcat(t, "に");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけが");
else strcat(t, "は");
} else if(StringCmp(s, "I")) {
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "に");
if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
} else if(StringCmp(s, "J")) {
strcat(t, "事");
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "に");
if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
} else if(StringCmp(s, "K")) {
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "から");
} else if(StringCmp(s, "L")) {
if((jpEmphasis & JP_EMPHASIS_ONLY)
|| (jpEmphasis & JP_EMPHASIS_SEULEMENT))strcat(t, "へだけの");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "へも");
else strcat(t, "への");
} else if(StringCmp(s, "N")) {
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "の");
} else if(StringCmp(s, "S")) {
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "として");
} else if(StringCmp(s, "T")) {
if(jpEmphasis & JP_EMPHASIS_HOU) strcat(t, "の方");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
strcat(t, "と");
} else if(StringCmp(s, "U")) {
strcat(t, "事");
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
} else if(StringCmp(s, "V")) {
strcat(t, "事");
if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
else strcat(t, "を");
} else if(StringCmp(s, "W")) {
// if(jpEmphasis & JP_EMPHASIS_HOU) strcat(t, "の方");
if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "しか");
else if(jpEmphasis & JP_EMPHASIS_SEULEMENT) strcat(t, "だけ");
else if(jpEmphasis & JP_EMPHASIS_DEMO) strcat(t, "でも");
else if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "も");
else strcat(t, "を");
} else if(StringCmp(s, "Y")) {
strcat(t, "よりも");
} else if(StringCmp(s, "<にとって>")) {
strcat(t, "にとって");
} else if(StringCmp(s, "<の言うことを>")) {
if(jpEmphasis & JP_EMPHASIS_MO) strcat(t, "の言うことも");
else strcat(t, "の言うことを");
} else if(StringCmp(s, "<のために>")) {
strcat(t, "のために");
if(jpEmphasis & JP_EMPHASIS_ONLY) strcat(t, "しか");
} else {
// 該当なし
return(FALSE);
}
if(prtControl != PRT_CONTROL_DISABLE) // PRT_CONTROL_REPLACEでは表示する
MyPrintf(t);
return(TRUE);
}
//
// jpChangeをメタキャラから設定
//
BOOL
SetJpChange(char c, TOKEN *p, JP_CHANGE *jpChange, PRT_CONTROL *prtControl, BOOL *extendFlag)
{
switch(c) {
case 'a':
*jpChange = JP_CHANGE_ADJECTIVE;
break;
case 'c':
*jpChange = JP_CHANGE_ADVERB;
break;
case 'e':
*jpChange = JP_CHANGE_ABLE;
break;
case 'f':
*jpChange = JP_CHANGE_FORCE;
break;
case 'g':
*jpChange = JP_CHANGE_PLEASE;
break;
case 'h':
*jpChange = JP_CHANGE_TAI;
break;
case 'i':
*jpChange = JP_CHANGE_IF;
break;
case 'l':
*jpChange = JP_CHANGE_LETS;
break;
case 'n':
*jpChange = JP_CHANGE_NEGATIVE;
break;
case 'o':
*jpChange = JP_CHANGE_ORDER;
break;
case 'p':
*jpChange = JP_CHANGE_PASSE;
break;
case 'r':
*jpChange = JP_CHANGE_RESPECT;
break;
case 's':
*jpChange = JP_CHANGE_STOP;
break;
case 't': // Tense, jpPropの一部を拡張
*extendFlag = TRUE;
break;
case 'v': // Make VISIBLE
*prtControl = PRT_CONTROL_UNCONDITIONAL;
break;
case 'x': // JP_KIND_FALLOIR用
if(p->jpProp & JP_PROP_NEGATIVE)
*jpChange = JP_CHANGE_PLEASE;
else
*jpChange = JP_CHANGE_ADJECTIVE;
break;
case 'y': // JP_KIND_DEVOIR用
if(p->jpProp & JP_PROP_NEGATIVE)
*jpChange = JP_CHANGE_NEGATIVE;
else
*jpChange = JP_CHANGE_ADJECTIVE;
break;
case 'z':
*jpChange = JP_CHANGE_CONT;
break;
default:
return(FALSE);
}
return(TRUE);
}
//
// 動詞(+目的語1+目的語2)を表示
//
void
PrintOutVerb(TOKEN *subject, TOKEN *verb, JP_CHANGE jpChange)
{
if(verb == NULL) {
PrintOutTokens(NULL, subject, JP_CHANGE_NONE);
return;
}
if(verb->prtControl & PRT_CONTROL_DISPLAYED)
return;
JP_VERB const *jpVerb = (JP_VERB *)verb->which;
if(jpVerb == NULL) { // 最後の候補 = 一番つぶしが効く?
VERB *dic = (VERB *)verb->what;
jpVerb = &(dic->jpVerb)[dic->proposed - 1];
}
// Il n'y a plus de neige. もっと雪がない -> もう雪がない
// <雪>がJP_PROP_NEGATIVEを持っていなければならない
if(verb->object1 && (verb->object1->frPart & FR_PART_NOUN))
ExtendTense(verb, verb->object1);
if(verb->object2 && (verb->object2->frPart & FR_PART_NOUN))
ExtendTense(verb, verb->object2);
if(verb->child)
SortToken(verb->child, verbSortTable);
char str_sub[100], str_obj[100], str_verb[100];
DevideVerbJapanese(jpVerb->japanese, str_sub, str_obj, str_verb);
int cntSubject = 0;
if(subject) cntSubject = CountTokensWChild(subject->child);
// 文章本体の前に、表示すべきもの
for(TOKEN *p = verb->child; p; p = p->next) {
if(ShallPrintOutBeforeVerb(p)) {
p->jpEmphasis |= JP_EMPHASIS_COMMA;
PrintOutToken(verb, p, JP_CHANGE_ADVERB);
}
}
if(CountTokensWChild(verb->child) >= cntSubject + 3
|| (jpVerb->jpHint & JP_HINT_EXADVERB1)) {
// 副詞1、主語、副詞2、目的語の順に表示
PrintOutTokens(verb, verb->child, JP_CHANGE_CONT, LeaveOneAdverb);
PrintOutSubjectObject(str_sub, str_obj, subject, verb);
} else {
// 主語、目的語、副詞の順に表示
PrintOutSubjectObject(str_sub, str_obj, subject, verb);
}
PrintOutTokens(verb, verb->child, JP_CHANGE_ADVERB);
PrintOutMacroStr(str_verb, subject, verb, jpChange);
PrintOutVerbTail3(verb, jpVerb->jpKind, jpChange);
if(IsObjectMatch(verb->frPart, FR_PART_SENTENCE_QUE)
&& verb->prtControl == PRT_CONTROL_ENABLE) // != PRT_CONTROL_REPLACED
MyPrintf("事");
}
// 文章の前に表示する副詞の中で、最後のTokenを探す
TOKEN
*GetLastFrontAdverb(TOKEN *start)
{
TOKEN *p;
TOKEN *last = NULL;
for(p = start; p; p = p->next) {
if(LeaveOneAdverb(p)) last = p;
}
return(last);
}
// 文章本体の前に、表示したほうが良いか?
BOOL
ShallPrintOutBeforeVerb(TOKEN *p)
{
if(IsObjectMatch(p, FR_PART_INDEPENDENCE_ALL))
return(TRUE);
if(p->jpEmphasis & JP_EMPHASIS_COMMA)
return(TRUE);
// 文章を従えた前置詞
if((p->frPart & FR_PART_PREPOSIT)
&& p->object1
&& (p->object1->frPart & FR_PART_VERB))
return(TRUE);
// 私は何度この詩集を読んだだろう! -> 何度、私はこの詩集を読んだだろう!
if(IsObjectMatch(p, FR_PART_ADVERB_EXCLAMINATION)
|| SearchToken(FR_PART_ADVERB_EXCLAMINATION, p->child))
return(TRUE);
if((p->frPart & FR_PART_INTERROGATIVE)
|| (p->frPart & FR_PART_COMBINE)
|| IsObjectMatch(p, FR_PART_PREPOSIT_PAR)
|| HasRelative(p))
return(TRUE);
// 埋め込むには、長すぎる
if(CountTokensWChild(p->child)
+ CountTokensWChild(p->subject)
+ CountTokensWChild(p->object1)
+ CountTokensWChild(p->object2) >= 4) {
p->jpEmphasis |= JP_EMPHASIS_COMMA;
return(TRUE);
}
return(FALSE);
}
// 1つのTOKENを残しているか?
// eg) ウィーンで、<1827年3月26日>、彼は死んだ
// -> ウィーンで、彼は<1827年3月26日>死んだ
BOOL
LeaveOneAdverb(TOKEN *p)
{
TOKEN *q = p->next;
while(q) {
if(CanBeLastAdverb(q))
return(TRUE);
q = q->next;
}
return(FALSE);
}
BOOL
CanBeLastAdverb(TOKEN *p)
{
if((p->jpEmphasis & JP_EMPHASIS_COMMA)
|| (p->prtControl & PRT_CONTROL_DISABLE)
|| (p->prtControl & PRT_CONTROL_DISPLAYED))
return(FALSE);
if((p->frPart & FR_PART_ADVERB)
|| (p->frPart & FR_PART_ADJECTIVE)
|| (p->frPart & FR_PART_PREPOSIT)
|| IsObjectMatch(p, FR_PART_NOUN_GENERAL))
return(TRUE);
return(FALSE);
}
void
PrintOutSubjectObject(char *str_sub, char *str_obj, TOKEN *subject, TOKEN *verb)
{
int cntObjects = CountTokensWChild(verb->object1)
+ CountTokensWChild(verb->object2);
if(verb->object1
&& (SearchToken(FR_PART_SENTENCE_ALL, verb->object1) // 助動詞を含まない
|| SearchToken(FR_PART_RELATIVE_ALL, verb->object1->child)))
cntObjects += 10;
if(verb->object2
&& (SearchToken(FR_PART_VERB_ALL, verb->object2) // 近く動詞を含む
|| SearchToken(FR_PART_RELATIVE_ALL, verb->object2->child)))
cntObjects += 10;
if(subject
&& *str_sub
&& subject->prtControl == PRT_CONTROL_ENABLE
&& cntObjects >= 7) {
PrintOutMacroStr(str_obj, subject, verb, JP_CHANGE_NONE);
if(verb->synSubject // 何をするのかを、知らず -> 何をするのかを知らず
&& cntObjects >= 6)
MyPrintf("、");
PrintOutMacroStr(str_sub, subject, verb, JP_CHANGE_NONE);
} else {
PrintOutMacroStr(str_sub, subject, verb, JP_CHANGE_NONE);
PrintOutMacroStr(str_obj, subject, verb, JP_CHANGE_NONE);
}
}
//
// "."を手がかりに文字列を分割
//
void
DevideVerbJapanese(char *japanese, char *subject, char *object, char *verb)
{
char *s = japanese,
*p = verb;
subject[0] = object[0] = verb[0] = '\0';
while(TRUE) {
*p = *s;
if(*s == '\0')
break;
if(*s == '.') {
s++; *p = '\0';
p = verb;
if(subject[0])
PrintInternalError( "Internal Error <DevideVerbJapanese> <%s>\n", japanese);
if(object[0])
strcpy(subject, object);
strcpy(object, verb);
} else {
p++; s++;
}
}
}
//
// 動詞情報の拡張などを行ってから、日本語を表示
//
void
PrintOutVerbTail3(TOKEN *p, JP_KIND jpKind, JP_CHANGE jpChange)
{
FR_ATTRIB frAttrib = p->frAttrib;
FR_TENSE frTense = p->frTense;
JP_PROP jpProp = p->jpProp;
JP_EMPHASIS jpEmphasis = p->jpEmphasis;
TOKEN *from;
for(from = p->jpExtendFrom; from; from = from->jpExtendFrom) {
if(from->frAttrib) frAttrib = from->frAttrib;
if(from->frTense) frTense = from->frTense;
jpProp = jpProp | (from->jpProp * JP_PROP_NEGATIVE);
jpEmphasis |= from->jpEmphasis;
}
// 動詞は、各自が持っている時勢を使う
if( (p->frPart & FR_PART_VERB)
&& !(p->frTense & FR_TENSE_ORIGIN)) {
frAttrib = p->frAttrib;
frTense = p->frTense;
}
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, jpChange, jpEmphasis, TRUE);
}
//
// S V A, S V O Aのように形容詞・副詞で言い切る日本語訳に備えて
// Aにも必要な情報をVから供給する
//
void
ExtendTense(TOKEN *verb, TOKEN *object)
{
if(object == NULL) return;
object->jpProp |= (verb->jpProp * (JP_PROP_NEGATIVE | JP_PROP_QUESTION));
object->jpExtendFrom = verb;
}
//
// マクロ文字列を表示
//
void
PrintOutMacroStr(char *ptr, TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
unsigned char prevChar = '\0'; // 直前のキャラクタ(Shift JIS判別用)
PRT_CONTROL prtControl = PRT_CONTROL_ENABLE;
JP_EMPHASIS jpEmphasis = JP_EMPHASIS_NONE;
JP_CHANGE savJpChange = jpChange; // JP_CHANGEを保存
BOOL extendFlag = FALSE; // frTense, jpPropの一部を拡張するか?
while(*ptr) {
if((0x80 <= prevChar && prevChar <= 0x9f)
|| (0xe0 <= prevChar && prevChar <= 0xff)) {
prevChar = '\0';
MyPrintf("%c", *ptr++); // 2バイトコードの2バイト目
} else if(*ptr == '%') {
if(ptr[1] == '%') {
MyPrintf("%%");
ptr += 2;
} else {
while(1) {
if(*++ptr == '0') {
if(extendFlag) ExtendTense(p, p->subject);
if(p->synSubject) {
PrintOutMacroStr2(parent, p->subject, jpChange, &jpEmphasis, &prtControl);
} else {
prtControl = PRT_CONTROL_DISABLE;
}
extendFlag = FALSE;
jpChange = savJpChange;
} else if(*ptr == '1') {
if(extendFlag) ExtendTense(p, p->object1);
PrintOutMacroStr2(parent, p->object1, jpChange, &jpEmphasis, &prtControl);
extendFlag = FALSE;
jpChange = savJpChange;
} else if(*ptr == '2') {
if(extendFlag) ExtendTense(p, p->object2);
PrintOutMacroStr2(parent, p->object2, jpChange, &jpEmphasis, &prtControl);
extendFlag = FALSE;
jpChange = savJpChange;
} else if(*ptr == '3') {
if(extendFlag) ExtendTense(p, p->child);
PrintOutMacroStr2(parent, p->child, jpChange, &jpEmphasis, &prtControl);
extendFlag = FALSE;
jpChange = savJpChange;
} else if(PrintOutJpPreposition(ptr, jpEmphasis, prtControl)) {
jpEmphasis = JP_EMPHASIS_NONE;
if(*ptr == '<') {
while(*ptr && *ptr != '>') ptr++;
}
} else if(SetJpChange(*ptr, p, &jpChange, &prtControl, &extendFlag)) {
} else
break;
}
}
} else {
MyPrintf("%c", *ptr);
prevChar = *ptr++; // 1文字前のキャラクタ
}
}
}
void
PrintOutMacroStr2(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange, JP_EMPHASIS *jpEmphasis, PRT_CONTROL *prtControl)
{
if(p == NULL
|| (p->prtControl & PRT_CONTROL_DISPLAYED)) {
*prtControl = PRT_CONTROL_DISABLE;
} else {
PRT_CONTROL savControl = p->prtControl;
if(*prtControl == PRT_CONTROL_UNCONDITIONAL)
p->prtControl = PRT_CONTROL_ENABLE;
PrintOutTokens(parent, p, jpChange);
p->prtControl = PRT_CONTROL_DISPLAYED;
*jpEmphasis = p->jpEmphasis;
*prtControl = savControl;
}
}
//
// 動詞の活用を表示(再帰構造)
//
void
PrintOutVerbTail2(JP_KIND jpKind, FR_ATTRIB frAttrib, FR_TENSE frTense, JP_PROP jpProp, JP_CHANGE jpChange, JP_EMPHASIS jpEmphasis, BOOL isRoot)
{
JP_KIND jpKindTail = JP_KIND_NONE; // 助動詞の種類
if(jpEmphasis & JP_EMPHASIS_NOTAIL) return;
if((frTense & FR_TENSE_ORDER)
&& jpChange == JP_CHANGE_STOP) { // <voir> Paris et mourir. パリを<見よう> -> パリを<見て>
PrintOutVerbOrder(jpKind, frAttrib, frTense, jpProp, jpChange, isRoot);
} else if(jpProp & JP_PROP_QUESTION) {
jpProp &= (~JP_PROP_QUESTION);
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_QUESTION, jpEmphasis, FALSE);
if(jpKind != JP_KIND_NONE) {
if(jpChange == JP_CHANGE_EXCLAME) MyPrintf("の"); // Combien de temps n'avons-nous pas perdu! 我々はなんて多くの時間を失った<か→の>だろう!
else MyPrintf("か");
}
} else if(frTense & FR_TENSE_FUTURE_SIMPLE) {
frTense = (FR_TENSE)(frTense & (~FR_TENSE_FUTURE_SIMPLE));
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_STOP, jpEmphasis, FALSE);
if(jpChange != JP_CHANGE_ADJECTIVE) { // quand je rentrerai. 私が帰るだろう時 -> 私が帰る時
if(jpKind == JP_KIND_DA || jpKind == JP_KIND_KEIYODOSHI || jpKind == JP_KIND_RENTAISHI)
MyPrintf("ろう");
else if(jpKind != JP_KIND_NONE)
MyPrintf("だろう");
}
jpKindTail = JP_KIND_NONE;
} else if((frTense & FR_TENSE_PASSE)
&& jpChange != JP_CHANGE_ADVERB // <して> の過去形も<して>
&& jpChange != JP_CHANGE_RESPECT) { // 閉じ込められた<れた> -> 閉じ込められた
frTense = (FR_TENSE)(frTense & (~FR_TENSE_PASSE));
if(jpChange == JP_CHANGE_IF) { // <すれば>の過去形<していれば>
frTense = (FR_TENSE)(frTense & (~FR_TENSE_PROGRESSIVE));
if((jpKind & 0xfff0) == JP_KIND_IRU
|| (jpKind & 0xfff0) == JP_KIND_GODAN2) { // 動詞自体に<いる>が含まれる場合は、無視 eg)知っている
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_IF, jpEmphasis, FALSE);
} else {
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_PLEASE, jpEmphasis, FALSE);
jpKindTail = JP_KIND_IRU;
}
} else if(jpChange == JP_CHANGE_CONT) {
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_CONT, jpEmphasis, FALSE);
} else {
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_PASSE, jpEmphasis, FALSE);
}
// if(jpKind != JP_KIND_NONE) MyPrintf("た");
} else if((frTense & FR_TENSE_PROGRESSIVE)
&& !(jpProp & JP_PROP_CONDITION)) { // ~している
frTense = (FR_TENSE)(frTense & (~FR_TENSE_PROGRESSIVE));
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_PLEASE, jpEmphasis, FALSE);
jpKindTail = JP_KIND_IRU;
} else if(jpProp & JP_PROP_NEGATIVE) {
jpProp &= (~JP_PROP_NEGATIVE);
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_NEGATIVE, jpEmphasis, FALSE);
if(!(jpKind == JP_KIND_DEVOIR && isRoot) // しなくてもよ/い
&& jpKind != JP_KIND_NONE) {
MyPrintf("な"); // ない
jpKindTail = JP_KIND_KEIYOSHI;
} else {
jpKindTail = JP_KIND_KEIYOSHI;
}
} else if(jpProp & JP_PROP_PASSIVE) { // 受け身
jpProp &= (~JP_PROP_PASSIVE);
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_RESPECT, jpEmphasis, FALSE);
if(jpChange != JP_CHANGE_RESPECT) { // 閉じ込められ<られ>
jpKindTail = JP_KIND_RERU;
}
} else if(jpEmphasis & JP_EMPHASIS_NI) {
jpEmphasis -= JP_EMPHASIS_NI;
PrintOutVerbTail2(jpKind, frAttrib, frTense, jpProp, JP_CHANGE_MO, jpEmphasis, FALSE);
} else {
PrintOutJpChange(jpKind, jpChange);
}
if(jpKind != JP_KIND_NONE
&& jpKindTail != JP_KIND_NONE)
PrintOutJpChange(jpKindTail, jpChange);
}
//
// 命令形の表示
//
void
PrintOutVerbOrder(JP_KIND jpKind, FR_ATTRIB frAttrib, FR_TENSE frTense, JP_PROP jpProp, JP_CHANGE jpChange, BOOL isRoot)
{
if(jpKind == JP_KIND_NONE
|| jpChange == JP_CHANGE_NONE)
return;
if(!(frAttrib & FR_ATTRIB_PLURAL) // tu
|| (frTense & FR_TENSE_ORIGIN)) { // 原形
if(jpProp & JP_PROP_NEGATIVE) {
jpProp &= (~JP_PROP_NEGATIVE);
PrintOutVerbTail2(jpKind, frAttrib, FR_TENSE_NONE, jpProp, JP_CHANGE_STOP, JP_EMPHASIS_NONE, FALSE);
MyPrintf("な");
} else {
PrintOutVerbTail2(jpKind, frAttrib, FR_TENSE_NONE, jpProp, JP_CHANGE_ORDER, JP_EMPHASIS_NONE, FALSE);
}
} else if((frAttrib & FR_ATTRIB_PLURAL) // vous
&& (frAttrib & FR_ATTRIB_LEVEL2)) {
if(jpProp & JP_PROP_NEGATIVE) {
PrintOutVerbTail2(jpKind, frAttrib, FR_TENSE_NONE, jpProp, JP_CHANGE_STOP, JP_EMPHASIS_NONE, FALSE);
MyPrintf("で下さい");
} else {
PrintOutVerbTail2(jpKind, frAttrib, FR_TENSE_NONE, jpProp, JP_CHANGE_PLEASE, JP_EMPHASIS_NONE, FALSE);
MyPrintf("下さい");
}
} else if(jpKind != JP_KIND_NONE) { // nous
if(jpProp & JP_PROP_NEGATIVE) {
PrintOutVerbTail2(jpKind, frAttrib, FR_TENSE_NONE, jpProp, JP_CHANGE_ADJECTIVE, JP_EMPHASIS_NONE, FALSE);
MyPrintf("ようにしましょう");
} else {
PrintOutVerbTail2(jpKind, frAttrib, FR_TENSE_NONE, jpProp, JP_CHANGE_LETS, JP_EMPHASIS_NONE, FALSE);
MyPrintf("う");
}
}
}
//
// Token Listを表示
//
int
PrintOutTokens(TOKEN *parent, TOKEN *start, JP_CHANGE jpChange, BOOL (*Eval)(TOKEN *))
{
TOKEN *p;
int cnt = 0;
for(p = start; p; p = p->next) {
if(Eval == NULL
|| (Eval)(p)) {
PrintOutToken(parent, p, jpChange);
cnt++;
}
}
return(cnt);
}
//
// TOKENを表示
//
void
PrintOutToken(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
FR_PART frPart = p->frPart;
if(frPart & FR_PART_COMBINE) PrintOutCombine(parent, p, jpChange);
else if(frPart & FR_PART_ARTICLE) PrintOutArticle(parent, p);
else if(frPart & FR_PART_VERB) PrintOutVerb(p->subject, p, jpChange);
else if(frPart & FR_PART_PREPOSIT) PrintOutPreposition(parent, p, jpChange);
else if(frPart & FR_PART_ADJECTIVE) PrintOutAdjective(parent, p, jpChange);
else if(frPart & FR_PART_ADVERB) PrintOutAdverb(parent, p, jpChange);
else if(frPart & FR_PART_NOUN) PrintOutNoun(parent, p);
else if(frPart & FR_PART_NUMETRIC) PrintOutNumetric(parent, p, jpChange);
else if(frPart & FR_PART_RELATIVE) PrintOutRelative(parent, p, jpChange);
else if(frPart & FR_PART_INTERROGATIVE) PrintOutInterrogative(parent, p, jpChange);
else if(frPart & FR_PART_SPECIAL) PrintOutSpecial(parent, p, jpChange);
else if(frPart & FR_PART_INDEPENDENCE) PrintOutIndependence(parent, p, jpChange);
else if(frPart & FR_PART_CONJUNCTION) PrintOutConjunction(parent, p, jpChange);
if( p->prtControl == PRT_CONTROL_ENABLE
&& IsObjectMatch(p, FR_PART_NUMETRIC_ALL) == FALSE
&& (p->jpEmphasis & JP_EMPHASIS_COMMA))
MyPrintf("、");
p->prtControl = PRT_CONTROL_DISPLAYED;
}
//
// 日本語動詞語尾の表示
//
void
PrintOutJpChange(JP_KIND jpKind, JP_CHANGE jpChange)
{
char tmp[10], *ret;
if(jpChange == JP_CHANGE_NONE) return;
switch(jpKind & (~0xf)) {
case JP_KIND_NONE: // 何もしない
return;
case JP_KIND_GODAN: // 五段活用
ret = (char *)jpVerbTailTable_Godan[jpKind & 0x0f][jpChange];
break;
case JP_KIND_GODAN2: // 否定:五段活用/肯定:上一段活用 eg)知っている/知らない
if(jpChange == JP_CHANGE_NEGATIVE) {
ret = (char *)jpVerbTailTable_Godan[jpKind & 0x0f][jpChange];
} else {
strcpy(tmp, "ってい");
strcat(tmp, (char *)jpVerbTailTable_Other[jpChange]);
ret = tmp;
}
break;
case JP_KIND_IRU: // 上一段活用
strcpy(tmp, (char *)jpVerbTailTable_Upper1[jpKind & 0x0f]);
strcat(tmp, (char *)jpVerbTailTable_Other[jpChange]);
ret = tmp;
break;
case JP_KIND_SHIMOICHI: // 下一段活用
strcpy(tmp, (char *)jpVerbTailTable_Lower1[jpKind & 0x0f]);
strcat(tmp, (char *)jpVerbTailTable_Other[jpChange]);
ret = tmp;
break;
case JP_KIND_SHIMOICHI2: // 下一段活用 (その2) 失う恋 -> 失われた恋
strcpy(tmp, (char *)jpVerbTailTable_Lower1[jpKind & 0x0f]);
strcat(tmp, (char *)jpVerbTailTable_Other2[jpChange]);
ret = tmp;
break;
case JP_KIND_NOROOT: // 語幹なし上/下一段活用
ret = (char *)jpVerbTailTable_Noroot[jpChange];
break;
case JP_KIND_KAHEN: // カ行変格活用
ret = (char *)jpVerbTailTable_Kahen[jpChange];
break;
case JP_KIND_SAHEN: // サ行変格活用
ret = (char *)jpVerbTailTable_Sahen[jpChange];
break;
case JP_KIND_SAHEN2: // サ行変格活用(その2) 怪我をする人 -> 怪我をした人
ret = (char *)jpVerbTailTable_Sahen2[jpChange];
break;
case JP_KIND_KEIYOSHI: // 形容詞
ret = (char *)jpVerbTailTable_Keiyoshi[jpChange];
break;
case JP_KIND_KEIYODOSHI: // 形容動詞
ret = (char *)jpVerbTailTable_KeiyoDoshi[jpChange];
break;
case JP_KIND_RENTAISHI: // 連体詞
ret = (char *)jpVerbTailTable_Rentaishi[jpChange];
break;
case JP_KIND_ADVERB: // 副詞
ret = (char *)jpVerbTailTable_Adverb[jpChange];
break;
case JP_KIND_ARU: // 在る
ret = (char *)jpVerbTailTable_Aru[jpChange];
break;
case JP_KIND_MASU: // ます
ret = (char *)jpVerbTailTable_Masu[jpChange];
break;
case JP_KIND_RASII: // らしい
ret = (char *)jpVerbTailTable_Rasii[jpChange];
break;
case JP_KIND_TA: // た
ret = (char *)jpVerbTailTable_Ta[jpChange];
break;
case JP_KIND_DA: // だ
ret = (char *)jpVerbTailTable_Da[jpChange];
break;
case JP_KIND_DESU: // です
ret = (char *)jpVerbTailTable_Desu[jpChange];
break;
case JP_KIND_DEVOIR:
ret = (char *)jpVerbTailTable_Devoir[jpChange];
break;
case JP_KIND_FALLOIR:
ret = (char *)jpVerbTailTable_Falloir[jpChange];
break;
case JP_KIND_POUVOIR:
ret = (char *)jpVerbTailTable_Pouvoir[jpChange];
break;
default:
goto Error;
}
MyPrintf(ret);
return;
Error:
PrintInternalError( "Internal Error <PrintOutJpChange>\n"
" jpKind = %x\n", jpKind);
TermProgram(-1);
}
// 冠詞の表示
void
PrintOutArticle(TOKEN *parent, TOKEN *p)
{
if(p->prtControl != PRT_CONTROL_ENABLE) return;
if(parent
&& parent->frPart == FR_PART_NOUN_GENERAL) {
if(parent->jpProp & JP_PROP_DATE) {
if(parent->jpProp & JP_PROP_UNIQUE) MyPrintf("毎"); // le mandi -> 毎月曜日
// JP_PROP_DATE without JP_PROP_UNIT should be "month"
return;
}
// la Terre (その)地球 -> 地球
// la livre (その)ポンド -> ポンド
if(parent->jpProp & (JP_PROP)(JP_PROP_UNIQUE | JP_PROP_UNIT))
return;
}
if(p->frPart == FR_PART_ARTICLE_INFINIT
&&(p->frAttrib & FR_ATTRIB_PLURAL)
&& parent
&& parent->frPart == FR_PART_NOUN_GENERAL) {
// des petits livres.
char *s = GetJpUnit(((JP_NOUN *)parent->which)->jpUnit);
if(*s) MyPrintf("(何%sかの)", s);
else MyPrintf("(幾らかの)");
} else if(p->frPart == FR_PART_ARTICLE_PARTIAL) {
// MyPrintf("(幾らかの)");
}else {
MyPrintf(((ARTICLE *)p->what)->japanese);
}
}
// 名詞にかかる言葉の優先順位
// eg) 若いどの少女 → どの若い少女?
FR_PATTERN nounSortTable[] = {
FR_PATTERN( CMP_TOKEN( FR_PART_ARTICLE_ALL), 1 ),
FR_PATTERN( CMP_TOKEN( FR_PART_INTERROGATIVE_ALL), 2 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ADJECTIVE_GENERAL_B), 3 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ADJECTIVE_EXCLAMINATION), 7 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ADJECTIVE_ALL), 4 ),
FR_PATTERN( CMP_TOKEN( FR_PART_ALL), 5 ),
FR_PATTERN( CMP_TOKEN( FR_PART_NUMETRIC_ALL), 6 ),
FR_PATTERN( CMP_TOKEN( FR_PART_VERB_ALL), 7 ),
FR_PATTERN( CMP_TOKEN( FR_PART_RELATIVE_ALL), 8 ),
FR_PATTERN( CMP_TOKEN( FR_PART_NONE )),
};
//
// 名詞の表示
//
void
PrintOutNoun(TOKEN *parent, TOKEN *p)
{
if(p->frPart & FR_PART_COMBINE) {
if(p->object1) PrintOutNoun(parent, p->object1);
if(p->object2) PrintOutNoun(parent, p->object2);
return;
}
if(p->frPart == FR_PART_NOUN_VERB) {
JP_EMPHASIS savJpEmphasis = p->jpEmphasis;
p->jpEmphasis -= JP_EMPHASIS_NI;
PrintOutVerb(NULL, p, JP_CHANGE_ADJECTIVE);
if(p->prtControl == PRT_CONTROL_ENABLE) // != PRT_CONTROL_REPLACED
MyPrintf("事");
p->jpEmphasis = savJpEmphasis;
if(savJpEmphasis & JP_EMPHASIS_NI) MyPrintf("も");
return;
}
if(p->child) {
SortToken(p->child, nounSortTable);
// PrintOutTokens(NULL, p->child, FR_PART_VERB, JP_CHANGE_ADJECTIVE);
PrintOutTokens(p, p->child, JP_CHANGE_ADJECTIVE);
}
if(p->prtControl != PRT_CONTROL_ENABLE)
return;
if((p->jpProp & JP_PROP_DATE) && p->value2)
MyPrintf("%d年", p->value2);
if(p->frPart == FR_PART_NOUN_GENERAL) {
PrintOutGeneralNoun(parent, p);
} else {
PrintOutPronoun(parent, p);
}
// 最も美しい街の一つ
if(IsWordOwner(p, FR_ATTRIB_ONE_OF)) {
char *unit = GetJpUnit(p->jpUnit);
if(unit[0] == '\0') unit = "つ";
MyPrintf("の1%s", unit);
}
if(IsObjectMatch(p, FR_PART_NOUN_PERSONAL)
&& (p->jpEmphasis & JP_EMPHASIS__MEME)) {
// moi-m]me.
MyPrintf("自身");
}
}
void
PrintOutPronoun(TOKEN *parent, TOKEN *p)
{
if(p->which == NULL) { // 日本語訳が確定していない時は、一番つぶしが効くものを
PRONOUN *pronoun = (PRONOUN *)p->what;
p->which = &pronoun->jpPronoun[pronoun->proposed-1];
}
if((p->jpEmphasis & JP_EMPHASIS_ROOT)
&& (p->jpProp & JP_PROP_NEGATIVE)) {
void *savWhich = p->which;
// Rien de autre. 他の誰 ->他の誰もいない。
SelectJpPronoun2(p, p->jpProp);
// 誰もいない<も> -> 誰もいない
if(savWhich != p->which)
p->jpEmphasis = JP_EMPHASIS_NONE;
}
JP_PRONOUN *jpPronoun = (JP_PRONOUN *)p->which;
MyPrintf(jpPronoun->japanese);
}
void
PrintOutGeneralNoun(TOKEN *parent, TOKEN *p)
{
if(!strcmp("heure", GetTokenFrench(p))
&& p->value2) {
if(p->value2 > 0) MyPrintf("時%d分", p->value2);
else MyPrintf("時%d分前", - p->value2);
return;
}
if(p->which == NULL) { // 日本語訳が確定していない時は、一番つぶしが効くものを
NOUN *noun = (NOUN *)p->what;
p->which = &noun->jpNoun[noun->proposed-1];
}
PrintOutMacroStr(((JP_NOUN *)p->which)->japanese, NULL, p, JP_CHANGE_STOP);
if(!(p->prtControl & PRT_CONTROL_NO_PLUS)) {
if(p->frAttrib & FR_ATTRIB_PLUS) MyPrintf("以上");
if(p->frAttrib & FR_ATTRIB_MOINS) MyPrintf("以下");
}
if(p->object1
&& IsObjectMatch(p->object1, FR_PART_NOUN_GENERAL)) { // 名 + 姓 ジュリアン<・ソレル>
MyPrintf("・");
PrintOutTokens(p, p->object1, JP_CHANGE_STOP);
}
if(p->object2
&& IsObjectMatch(p->object2, FR_PART_NOUN_GENERAL)) { // 敬称など、 ポール<さん>
PrintOutTokens(p, p->object2, JP_CHANGE_STOP);
}
if((p->jpProp & JP_PROP_DATE) && p->value)
MyPrintf("%d日", p->value);
}
// 形容詞の表示
void
PrintOutAdjective(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->prtControl != PRT_CONTROL_ENABLE) return;
if(IsObjectMatch(parent, FR_PART_SENTENCE_ALL)
&& jpChange == JP_CHANGE_CONT)
jpChange = JP_CHANGE_ADVERB; // 不幸<で> -> 不幸<に>
if(IsObjectMatch(p, FR_PART_ADJECTIVE_GENERAL))
PrintOutGeneralAdjective(parent, p, jpChange);
else
PrintOutProadjective(parent, p, jpChange);
}
void
PrintOutGeneralAdjective(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
JP_ADJECTIVE *jpAdjective = (JP_ADJECTIVE *)p->which;
if(jpAdjective == NULL) { // 最後の候補 = 一番つぶしが効く
ADJECTIVE *dic = (ADJECTIVE *)p->what;
jpAdjective = &dic->jpAdjective[dic->proposed - 1];
}
if(p->child
&& strstr(jpAdjective->japanese, "%c3") == NULL) // とても彼が成功し嬉しい ->彼が成功しとても嬉しい
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
// 比較級の表示
if(SearchToken(FR_PART_CONJUNCTION_THAN, p->child) == NULL)
PrintOutCompare(parent, p);
PrintOutMacroStr(jpAdjective->japanese, NULL, p, JP_CHANGE_NONE);
// PrintOutVerbTail2(jpAdjective->jpKind, p->frAttrib, p->frTense, p->jpProp, jpChange, p->jpEmphasis, TRUE);
PrintOutVerbTail3(p, jpAdjective->jpKind, jpChange);
}
void
PrintOutProadjective(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->child)
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
JP_PROADJECTIVE *jpAdjective = (JP_PROADJECTIVE *)p->which;
if(jpAdjective == NULL) { // 最後の候補 = 一番つぶしが効く
PROADJECTIVE *dic = (PROADJECTIVE *)p->what;
jpAdjective = &dic->jpProadjective[dic->proposed - 1];
}
MyPrintf(jpAdjective->japanese);
}
//
// 比較級の表示
//
void
PrintOutCompare(TOKEN *parent, TOKEN *p)
{
if(p == NULL) return;
if(p->frAttrib & FR_ATTRIB_PLUS) {
TOKEN *than = SearchToken(FR_PART_CONJUNCTION_THAN, p->child);
if(than) {
if(IsObjectMatch(than->object1, FR_PART_SENTENCE_NORMAL))
MyPrintf("から");
else
MyPrintf("より");
if(p->value != 0) MyPrintf("%d倍", p->value);
} else if(parent && (parent->jpProp & JP_PROP_NEGATIVE)
|| (p->jpProp & JP_PROP_NEGATIVE)) {
MyPrintf("もう");
} else {
if(p->value != 0) MyPrintf("%d倍", p->value);
else MyPrintf("もっと");
}
} else if(p->frAttrib & FR_ATTRIB_MOINS) {
MyPrintf("より低度に");
} else if(p->frAttrib & FR_ATTRIB_NE_MOINS) {
MyPrintf("に劣らず");
} else if(p->frAttrib & FR_ATTRIB_AUSSI) {
TOKEN *than = SearchToken(FR_PART_CONJUNCTION_THAN, p->child);
if(than
&& than->object1 == NULL)
MyPrintf("かつ"); // Marie est aussi inteligent que jolie.
else
MyPrintf("くらい");
} else if(p->frAttrib & FR_ATTRIB_SI) {
if(SearchToken(FR_PART_CONJUNCTION_THAN, p->child))
MyPrintf("ほど");
else
MyPrintf("そんなに");
} else if(p->frAttrib & FR_ATTRIB_LE_PLUS) {
MyPrintf("最も");
} else if(p->frAttrib & FR_ATTRIB_LE_MOINS) {
MyPrintf("最も低度に");
}
}
//
// 副詞の表示
//
void
PrintOutAdverb(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->child)
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
if(p->prtControl != PRT_CONTROL_ENABLE) return;
if((p->frAttrib & FR_ATTRIB_COMPARE)
&& SearchToken(FR_PART_CONJUNCTION_THAN, p->child) == NULL)
PrintOutCompare(parent, p);
else if(p->frAttrib & FR_ATTRIB_TOP)
PrintOutCompare(parent, p);
if(p->frPart == FR_PART_ADVERB_ADVERB
|| p->frPart == FR_PART_ADVERB_EXCLAMINATION) {
JP_PROADVERB *jpAdv = (JP_PROADVERB *)p->which;
MyPrintf(jpAdv->japanese);
} else if(p->frPart == FR_PART_ADVERB_PLUS) {
if(IsWordOwner(p, FR_ATTRIB_COMPARE) == NULL
&& IsWordOwner(p, FR_ATTRIB_TOP) == NULL) {
JP_PROADVERB *jpAdv = (JP_PROADVERB *)p->which;
MyPrintf(jpAdv->japanese);
}
} else if(p->frPart == FR_PART_ADVERB_TOUT) {
if(p->value) MyPrintf("%d(つ/人)共", p->value);
else MyPrintf("全て");
} else {
JP_ADVERB *jpAdverb = (JP_ADVERB *)p->which;
if(jpAdverb == NULL) { // 最後の候補 = 一番つぶしが効く
ADVERB *dic = (ADVERB *)p->what;
jpAdverb = &dic->jpAdverb[dic->proposed - 1];
}
if( (p->frPart & FR_PART_INTERROGATIVE)
&& !(p->jpProp & JP_PROP_NEGATIVE)) { // eg) O| n'est pas la voiture? 車はどこにないか?
// JP_PROP_QUESTIONなどを無視 eg) O| est la voiture? 車はどこか? -> どこだ?
MyPrintf(jpAdverb->japanese);
PrintOutJpChange(jpAdverb->jpKind, jpChange);
} else {
PrintOutMacroStr((char *)jpAdverb->japanese, NULL, p, JP_CHANGE_NONE);
PrintOutVerbTail3(p, jpAdverb->jpKind, jpChange);
}
}
if(p->jpEmphasis & JP_EMPHASIS_HA) // Hier, c'{tait dimanche. ->昨日月曜日だった -> 昨日<は>
MyPrintf("は");
}
//
// 数値の表示
//
void
PrintOutNumetric(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
char *unit = "";
if(p->child)
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
if(p->prtControl == PRT_CONTROL_DISABLE) return;
if(p->jpUnit) {
unit = GetJpUnit(p->jpUnit);
} else if(parent) {
if(parent->frPart == FR_PART_NOUN_GENERAL && parent->which) {
JP_NOUN *jpNoun = (JP_NOUN *)parent->which;
unit = GetJpUnit(jpNoun->jpUnit);
} else if(parent->frPart & FR_PART_NOUN) { // 中性代名詞とか、目的代名詞とか
unit = GetJpUnit(parent->jpUnit);
if(unit[0] == '\0') unit = "(つ/人)"; // il y en a deux. -> 2<つ/人>ある。
} else {
unit = "(つ/人)"; // これが一番無難?
}
}
if( p->frPart != FR_PART_NUMETRIC_NUMBER
|| parent == NULL
// Je n'ai pas <une> robe. 私は一つ<も>洋服を持っていない
|| ((parent->frPart & FR_PART_VERB) && (parent->jpProp & JP_PROP_NEGATIVE))
// 一部の数詞は、動詞に掛けてある eg) 一冊の辞書を持っている -> 辞書を一冊持っている
// || IsObjectMatch(parent, (FR_PART)(FR_PART_NOUN_ALL | FR_PART_VERB_ALL)) == FALSE
|| (parent->jpProp & JP_PROP_UNIT)
|| p->value != 1)
; // 1件でも、あてはまれば、表示
else return; // きっと冠詞の un, une でしょう。
JP_KIND jpKind = JP_KIND_RENTAISHI;
int value = p->value;
if((p->prtControl & PRT_CONTROL_MINUS1)
&& value > 1)
value--;
if(p->frPart == FR_PART_NUMETRIC_NUMBER) {
MyPrintf("%d%s", value, unit);
if(value == 1
&& parent
&& !(parent->jpEmphasis & JP_EMPHASIS_ONLY)
&& (parent->jpProp & JP_PROP_NEGATIVE)) { // Je n'ai pas <une> robe. 私は一つ<も>洋服を持っていない
MyPrintf("も");
}
} else if(p->frPart == FR_PART_NUMETRIC_ORDER) {
MyPrintf("%d番目", p->value);
} else if(p->frPart == FR_PART_NUMETRIC_FRACTION) {
MyPrintf("分の%d", p->value);
} else if(p->frPart == FR_PART_NUMETRIC_COMBIEN) {
if(unit[0]) MyPrintf("何%s", unit);
else MyPrintf("どのくらい");
} else if(p->frPart == FR_PART_NUMETRIC_EXCLAMINATION) {
if(unit[0]) MyPrintf("何%s", unit);
else MyPrintf("何て多く");
} else if(p->frPart == FR_PART_NUMETRIC_CHOICE) {
MyPrintf("%d%sの中で", p->value, unit);
jpKind = JP_KIND_NONE;
} else {
PrintInternalError( "Internall Error <PrintOutNumetric>\n");
jpKind = JP_KIND_NONE;
}
if(parent == NULL
|| (parent && parent->jpUnit == JP_UNIT_UNIT)) {
} else {
PrintOutVerbTail3(p, jpKind, jpChange);
}
}
char
*GetJpUnit(JP_UNIT jpUnit)
{
switch(jpUnit) {
case JP_UNIT_KO: return "個";
case JP_UNIT_DAI: return "台";
case JP_UNIT_HITO: return "人";
case JP_UNIT_HON: return "本";
case JP_UNIT_SATU: return "冊";
case JP_UNIT_TSU: return "つ";
case JP_UNIT_HIKI: return("匹");
case JP_UNIT_TOU: return("頭");
case JP_UNIT_WA: return("羽");
case JP_UNIT_CHAKU: return "着";
}
return "";
}
//
// 前置詞の表示
//
void
PrintOutPreposition(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
JP_PREPOSITION *jpPreposition = (JP_PREPOSITION *)p->which;
if(jpPreposition == NULL) {
// もう一度、確認 (昔は、verb Tokenがwhich == NULLだったとか...)
jpPreposition = MatchParentPreposition(parent, p);
if(jpPreposition == NULL) {
// それでもだめなら、最後の候補 = 一番つぶしが効く
PREPOSITION *dic = (PREPOSITION *)p->what;
jpPreposition = &dic->jpPreposition[dic->proposed - 1];
}
}
if(p->prtControl == PRT_CONTROL_REPLACED) {
PrintOutTokens(NULL, p->object1, jpChange);
} else if(p->prtControl == PRT_CONTROL_ENABLE) {
PrintOutMacroStr(jpPreposition->japanese, NULL, p, JP_CHANGE_NONE);
PrintOutJpChange(jpPreposition->jpKind, jpChange);
}
}
//
// 関係代名詞/副詞の表示
//
void
PrintOutRelative(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
jpChange = JP_CHANGE_ADJECTIVE;
if(parent
&& (parent->jpEmphasis & JP_EMPHASIS_SENTENCE)) {
// 強調構文 窓を壊した私 -> 窓を壊した<のは>私
jpChange = JP_CHANGE_STOP;
}
if(p->child)
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
if(IsObjectMatch(p, FR_PART_RELATIVE_SUBJECT)
&& p->object1
&& (p->object1->frPart & FR_PART_VERB)) {
PrintOutVerb(NULL, p->object1, jpChange);
} else if(IsObjectMatch(p, FR_PART_RELATIVE_OBJECT)
&& p->object1) {
PrintOutVerb(p->object1->subject, p->object1, jpChange);
} else if(p->frPart == FR_PART_RELATIVE_ADVERB
&& p->object1) {
PrintOutVerb(p->object1->subject, p->object1, jpChange);
} else if(p->frPart == FR_PART_RELATIVE_SENTENCE
&& p->object1) {
PrintOutVerb(p->object1->subject, p->object1, jpChange);
}
if(jpChange == JP_CHANGE_STOP)
MyPrintf("のは");
}
//
// 連結詞の表示
//
void
PrintOutCombine(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->prtControl != PRT_CONTROL_ENABLE)
return;
if(p->child) {
if(p->frPart & FR_PART_NOUN)
PrintOutTokens(p, p->child, JP_CHANGE_ADJECTIVE);
else
PrintOutTokens(p, p->child, JP_CHANGE_CONT);
}
COMBINE *combine = (COMBINE *)p->what;
JP_COMBINE *jpCombine = (JP_COMBINE *)p->which;
if(jpCombine == NULL) {
jpCombine = &combine->jpCombine[combine->proposed - 1];
}
PrintOutMacroStr(jpCombine->japanese, parent, p, jpChange);
PrintOutVerbTail3(p, jpCombine->jpKind, jpChange);
}
//
// 接続詞の表示
//
void
PrintOutConjunction(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->child) {
PrintOutTokens(p, p->child, JP_CHANGE_CONT);
}
if(p->prtControl != PRT_CONTROL_ENABLE) return;
if(p->frPart == FR_PART_CONJUNCTION_THAN) {
if(p->child) PrintOutTokens(p, p->child, JP_CHANGE_STOP);
if(p->object1) PrintOutTokens(p, p->object1, JP_CHANGE_STOP);
PrintOutCompare(parent, parent);
}
}
//
// 疑問詞の表示(文章になっていない物のみ)
// eg) quoi d'autre?
//
void
PrintOutInterrogative(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->child) {
if((p->frPartChoice & FR_PART_ADVERB)
|| (p->frPartChoice & FR_PART_ADJECTIVE))
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
else
PrintOutTokens(p, p->child, JP_CHANGE_ADJECTIVE);
}
MyPrintf(((QUESTION *)p->what)->japanese);
JP_KIND jpKind = ((QUESTION *)p->what)->jpKind;
PrintOutVerbTail3(p, jpKind, jpChange);
}
BOOL
IsWordQuestion(TOKEN *p)
{
while(p) {
if(IsWordQuestion(p->child))
return(TRUE);
if(p->frPart & FR_PART_INTERROGATIVE)
return(TRUE);
p = p->next;
}
return(FALSE);
}
void
SortToken(TOKEN *start, FR_PATTERN *table)
{
retry:
TOKEN *p = start;
while(p && p->next) {
TOKEN *next = p->next;
if(GetTokenOrder(p, table) < GetTokenOrder(next, table)) {
SwapToken(p, next);
goto retry;
}
p = next;
}
}
int
GetTokenOrder(TOKEN *p, FR_PATTERN *table)
{
int ret = 0;
while(table->cmpToken.frPart != FR_PART_NONE) {
if(table->cmpToken.frPart == FR_PART_ALL
|| IsObjectMatch(p, table->cmpToken)) {
ret = table->order;
if(p->child) ret += GetTokenOrder(p->child, table);
if(p->object1) ret += GetTokenOrder(p->object1, table);
if(p->object2) ret += GetTokenOrder(p->object2, table);
return(ret);
}
table++;
}
return(0);
}
//
// FR_PART_SPECIALを(出来る範囲で)表示
//
void
PrintOutSpecial(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->child) {
if((p->frPartChoice & FR_PART_ADVERB)
|| (p->frPartChoice & FR_PART_ADJECTIVE))
PrintOutTokens(p, p->child, JP_CHANGE_ADVERB);
else
PrintOutTokens(p, p->child, JP_CHANGE_ADJECTIVE);
}
switch(p->frPart) {
case FR_PART_SPECIAL_COMMA:
MyPrintf("、");
break;
}
}
//
// FR_PART_INDEPENDENCEを表示
//
void
PrintOutIndependence(TOKEN *parent, TOKEN *p, JP_CHANGE jpChange)
{
if(p->frPart & FR_PART_COMBINE) {
if(p->object1)
PrintOutIndependence(parent, p->object1, jpChange);
if(p->object2)
PrintOutIndependence(parent, p->object2, jpChange);
}
if(p->child) {
PrintOutTokens(NULL, p->child, JP_CHANGE_ADJECTIVE);
}
if(p->prtControl != PRT_CONTROL_ENABLE)
return;
switch(p->frPart) {
case FR_PART_INDEPENDENCE_INTERJECTION:
if(p->what) {
INTERJECTION *interjection = (INTERJECTION *)p->what;
MyPrintf(interjection->japanese);
}
break;
case FR_PART_INDEPENDENCE_NOUN:
if(p->which == NULL) { // 日本語訳が確定していない時は、一番つぶしが効くものを
NOUN *noun = (NOUN *)p->what;
p->which = &noun->jpNoun[noun->proposed-1];
}
PrintOutMacroStr(((JP_NOUN *)p->which)->japanese, NULL, p, JP_CHANGE_STOP);
break;
}
}
//
// <Child> fieldを含めて、Tokenを数える
//
int
CountTokensWChild(TOKEN *start)
{
TOKEN *p;
int cnt = 0;
for(p = start; p; p = p->next) {
if(p->prtControl == PRT_CONTROL_DISABLE
|| p->prtControl == PRT_CONTROL_DISPLAYED)
continue;
cnt++;
if(p->subject) cnt += CountTokensWChild(p->subject);
if(p->child) cnt += CountTokensWChild(p->child);
if(p->object1) cnt += CountTokensWChild(p->object1);
if(p->object2) cnt += CountTokensWChild(p->object2);
}
return(cnt);
}
JP_KIND
GetJpKind(TOKEN *p)
{
if(p->frPart & FR_PART_COMBINE) {
// 後に表示される日本語
return(GetJpKind(p->object2));
}
else if(p->frPart & FR_PART_VERB) {
const JP_VERB *jpVerb = (JP_VERB *)p->which;
if(jpVerb == NULL) {
VERB *dic = (VERB *)p->what;
jpVerb = &dic->jpVerb[dic->proposed - 1];
}
return(jpVerb->jpKind);
}
else if(p->frPart & FR_PART_NOUN) {
return(JP_KIND_NONE);
}
else if(IsObjectMatch(p, FR_PART_ADJECTIVE_GENERAL)) {
JP_ADJECTIVE *jpAdjective = (JP_ADJECTIVE *)p->which;
if(jpAdjective == NULL) {
ADJECTIVE *dic = (ADJECTIVE *)p->what;
jpAdjective = &dic->jpAdjective[dic->proposed - 1];
}
return(jpAdjective->jpKind);
}
else if(IsObjectMatch(p, FR_PART_ADVERB_GENERAL)) {
JP_ADVERB *jpAdverb = (JP_ADVERB *)p->which;
if(jpAdverb == NULL) {
ADVERB *dic = (ADVERB *)p->what;
jpAdverb = &dic->jpAdverb[dic->proposed - 1];
}
return(jpAdverb->jpKind);
}
else if(IsObjectMatch(p, FR_PART_PREPOSIT_ALL)) {
JP_PREPOSITION *jpPreposition = (JP_PREPOSITION *)p->which;
if(jpPreposition == NULL) {
PREPOSITION *dic = (PREPOSITION *)p->what;
jpPreposition = &dic->jpPreposition[dic->proposed - 1];
}
return(jpPreposition->jpKind);
}
return(JP_KIND_NONE);
}